<template>
  <view>
    <template v-if="currentProduct">
      <view class="product-select-block">
        <view class="header">
          填写订单
        </view>
        <view class="product-info">
          <v-image
            height="196rpx"
            width="196rpx"
            border-radius="16rpx"
            :src="
              product.sku_type === 'SINGLE'
                ? product.image
                : currentProduct?.image
            "
            mode="aspectFill"
          />
          <view class="product-info-content">
            <view class="product-name">
              <view v-if="component.prime_flag" class="tag prime">
                精品
              </view>
              <view v-if="component.hot_selling_flag" class="tag hot-selling">
                热卖
              </view>
              <view v-if="component.new_arrival_flag" class="tag new-arrival">
                新品
              </view>
              <text>
                {{ component.name }}
              </text>
            </view>
            <view class="product-tag-list">
              <view v-for="tag in guaranteeTag" :key="tag" class="product-tag">
                {{ tag }}
              </view>
            </view>
            <view class="product-price">
              <view class="label">
                到手价
              </view>
              <v-price
                size="48rpx"
                sign-size="30rpx"
                :price="actualPrice"
                decimal-size="30rpx"
                :decimal-bold="false"
              />
              <view v-if="marketPrice" class="market-price">
                {{ `¥${marketPrice.toFixed(2)}` }}
              </view>
            </view>
          </view>
        </view>
        <view class="divider" style="margin: 24rpx 0" />
        <view class="spec-content">
          <view
            v-for="(spec, index) in displaySpecList"
            :key="index"
            class="spec-group"
          >
            <view class="spec-title">
              {{ spec.name }}
            </view>
            <view class="spec-list">
              <view
                v-for="(specValue, valueIndex) in spec.valueList"
                :key="valueIndex"
                class="spec-item"
                :class="{
                  active: specValue.selecting,
                  'sold-out': specValue.soldOut
                }"
                @click="selectSpec(spec.name, specValue.value)"
              >
                <view class="text">
                  {{ specValue.value }}
                </view>
              </view>
            </view>
          </view>
          <view class="product-select-item">
            <view class="label">
              购买数量
            </view>
            <view
              v-if="
                product?.quota_type === 'QUOTA' &&
                  product?.quota_purchase_rule?.marketing_text
              "
              class="purchase-rule"
            >
              {{ product.quota_purchase_rule.marketing_text }}
            </view>
            <view class="content">
              <v-input-number
                v-model="quantity"
                action
                :precision="0"
                :min="1"
                :max="maxQuantity"
              />
            </view>
          </view>
        </view>
      </view>
      <view v-if="userAddress" class="product-select-block">
        <view class="address-item" @click="userStore.getAddress">
          <v-icon
            size="44rpx"
            src="@/static/icons/product-select-address.svg"
          />
          <view class="address-content">
            <view class="address-main">
              {{ userAddress.detailInfo }}
            </view>
            <view class="address-sub">
              <text v-if="userAddress.userName">
                {{ userAddress.userName }}
              </text>
              <text v-if="userAddress.telNumber">
                {{ userAddress.telNumber }}
              </text>
            </view>
          </view>
          <wd-icon name="arrow-right" size="24rpx" color="#999999" />
        </view>
      </view>
      <view v-else class="order-info-block">
        <view class="order-info-item" @click="userStore.getAddress">
          <view class="label">
            收货地址
          </view>
          <view class="content">
            <!-- #ifdef MP-ALIPAY -->
            <v-icon size="44rpx" src="@/static/images/alipay-icon.png" />
            <view class="alipay-holder">
              支付宝地址导入
            </view>
            <!-- #endif -->
            <wd-icon name="arrow-right" size="24rpx" color="#999999" />
          </view>
        </view>
      </view>
      <view class="order-info-block">
        <view class="order-info-item">
          <view class="label">
            商品总额
          </view>
          <view class="content">
            <v-price size="30rpx" color="#333333" :price="totalPrice" />
          </view>
        </view>
        <view class="divider" />
        <view class="order-info-item">
          <view class="label">
            运费
          </view>
          <view
            v-if="!/^\d/.test(shippingText)"
            class="content"
            :class="{
              placeholder:
                shippingText === '-' || shippingText === '选择地址后展示'
            }"
          >
            {{ shippingText }}
          </view>
          <view v-else class="content">
            <v-price size="30rpx" color="#333333" :price="shippingText" />
          </view>
        </view>
        <template v-if="discount.amount">
          <view class="divider" />
          <view class="order-info-item">
            <v-icon
              size="48rpx"
              src="@/static/icons/landing-page-discount-coupon.svg"
            />
            <view class="label">
              优惠券
            </view>
            <view class="content">
              <v-price size="30rpx" :price="-discount.amount" />
            </view>
          </view>
        </template>
        <view class="divider" />
        <view class="order-info-item">
          <view class="label">
            应付金额
          </view>
          <view class="content">
            <v-price size="30rpx" :price="actualPrice" />
          </view>
        </view>
      </view>
      <view class="order-info-block">
        <view class="order-info-item" @click="showRemark">
          <view class="label">
            订单备注
          </view>
          <view class="content">
            <view class="remark" :class="{ placeholder: !remark }">
              {{ remark || '无备注' }}
            </view>
            <wd-icon name="arrow-right" size="24rpx" color="#999999" />
          </view>
        </view>
      </view>
      <landing-page-handy-buy
        v-if="landingPageData.handy_sku_list?.length"
        v-model="handyBuyList"
        :list="landingPageData.handy_sku_list"
      />
      <view class="submit-button-container">
        <v-button
          type="primary"
          :disabled="!!disabledText"
          @click="submitOrder"
        >
          {{ disabledText ? disabledText : '提交订单' }}
        </v-button>
      </view>
    </template>
    <m-textarea-popup
      v-model="editingRemark"
      v-model:show="isShowRemarkPopup"
      title="订单备注"
      edit
      @submit="sumitRemarkHandle"
    />
  </view>
</template>

<script setup lang="ts">
import LandingPageHandyBuy from './landing-page-handy-buy.vue';
import usePayment from '@/composables/use-payment';

const { payOrder } = usePayment();

const props = defineProps<{
  product: SpuVO;
  landingPageData: AdLandingPageVO;
  component: LandingPageGoodsItem;
  queryData: AnyObject;
}>();

const emits = defineEmits<{
  'show-popper': [];
  'hide-popper': [];
}>();

const landingStore = $store.landing();
const discount = computed(() => landingStore.discount);

const product = toRef(props, 'product');

const totalPrice = computed(() => {
  if (!currentProduct.value) return 0;
  return currentProduct.value.sell_price * quantity.value;
});

const marketPrice = computed(() => {
  const price = currentProduct.value?.market_price ?? 0;
  return price * quantity.value;
});

const actualPrice = computed(() => {
  if (!currentProduct.value) return 0;
  const val =
    totalPrice.value - discount.value.amount + (shippingFee.value ?? 0);
  return Math.max(val, 0);
});

const guaranteeTag = computed(() => {
  const list: string[] = [];
  const guarantees = props.component.guarantee_content?.guarantees;
  if (guarantees?.includes(1)) list.push('交易保障');
  if (guarantees?.includes(2)) list.push('消费者保障');
  if (guarantees?.includes(3)) list.push('破损补偿');
  if (guarantees?.includes(4)) list.push('七天无理由退货');
  if (guarantees?.includes(5)) list.push('正品保障');
  if (guarantees?.includes(6)) list.push('假一赔十');
  return list;
});

const selectingSpec = ref<{ name: string; value: string }[]>([]);
const selectSpec = (name: string, value: string) => {
  const newList = selectingSpec.value.concat([]);
  const index = newList.findIndex((spec) => spec.name === name);
  if (index >= 0) {
    newList.splice(index, 1, { name, value });
  } else {
    newList.push({ name, value });
  }
  const list = product.value?.sku_list;
  // 直接有这个sku
  const target = list.find((sku) =>
    sku.spec_info.every((skuSpec) =>
      newList.some(
        (selectingSpec) =>
          selectingSpec.name === skuSpec.name &&
          selectingSpec.value === skuSpec.value
      )
    )
  );
  if (target) {
    selectingSpec.value = newList;
    if (quantity.value > target.inventory) {
      quantity.value = target.inventory || 1;
    }
    return;
  }
  // 没有这个sku，尝试找一个有该规格的
  const secondTarget = list.find((sku) =>
    sku.spec_info.some(
      (skuSpec) => skuSpec.name === name && skuSpec.value === value
    )
  );
  if (secondTarget) {
    selectingSpec.value = secondTarget.spec_info.map((spec) => ({
      name: spec.name,
      value: spec.value
    }));
  } else {
    // 没有有这个规格的sku，无效按钮
  }
};
const initDefaultSelectingSpec = () => {
  const bestChooce = product.value?.sku_list.find((sku) => !!sku.def_sku_flag);
  if (bestChooce) {
    selectingSpec.value = bestChooce.spec_info.map((spec) => ({
      name: spec.name,
      value: spec.value
    }));
    return;
  }
  const firstChoose = product.value?.sku_list[0];
  if (firstChoose) {
    selectingSpec.value = firstChoose.spec_info.map((spec) => ({
      name: spec.name,
      value: spec.value
    }));
  }
};
onMounted(initDefaultSelectingSpec);

const handyBuyList = ref<HandySkuVO[]>([]);

const checkSkuInventory = (target: { name: string; value: string }[]) => {
  const item = product.value?.sku_list.find((sku) =>
    sku.spec_info.every((skuSpec) =>
      target.some(
        (selectingSpec) =>
          selectingSpec.name === skuSpec.name &&
          selectingSpec.value === skuSpec.value
      )
    )
  );
  return !!item && item.sale_status && item.inventory > 0;
};
const displaySpecList = computed(() => {
  if (!product.value?.spec_info) return [];
  const list: {
    name: string;
    valueList: { value: string; selecting: boolean; soldOut: boolean }[];
  }[] = [];
  const lastIndex = selectingSpec.value.length - 1;
  for (let i = 0; i < product.value.spec_info.length; i += 1) {
    const spec = product.value.spec_info[i];
    const rest = selectingSpec.value.filter(
      (selecting) => selecting.name !== spec.name
    );
    list.push({
      name: spec.name,
      valueList: spec.value_list.map((value) => ({
        value,
        selecting: selectingSpec.value.some(
          (selecting) =>
            selecting.name === spec.name && selecting.value === value
        ),
        soldOut:
          i === lastIndex &&
          !checkSkuInventory([...rest, { name: spec.name, value }])
      }))
    });
  }
  return list;
});
const currentProduct = computed(() => {
  if (!product.value?.sku_list) return undefined;
  const sku = product.value.sku_list.find((sku) =>
    sku.spec_info.every((skuSpec) =>
      selectingSpec.value.some(
        (selectingSpec) =>
          selectingSpec.name === skuSpec.name &&
          selectingSpec.value === skuSpec.value
      )
    )
  );
  return sku;
});

const shippingText = computed(() => {
  if (!currentProduct.value) return '-';
  if (userAddress.value === undefined) return '选择地址后展示';
  if (shippingFee.value === undefined) return '-';
  if (shippingFee.value === -1) return '该地区无法配送';
  if (shippingFee.value === 0) return '包邮';
  return `${shippingFee.value.toFixed(2)}`;
});
const shippingFee = ref<number>();
const getShippingInfo = async () => {
  if (!currentProduct.value) return;
  // 没库存查了会报错
  if (!currentProduct.value.inventory || !currentProduct.value.sale_status) {
    shippingFee.value = undefined;
    return;
  }
  shippingFee.value = undefined;
  const response = await $api.postOrderSubmitLandingTrial(
    {
      order_generate_req: [
        {
          sku_id: currentProduct.value.id,
          quantity: quantity.value,
          discount_type: discount.value.type,
          multilevel_reflux_setting_id: discount.value.id,
          landing_page_id: props.landingPageData.id
        },
        ...handyBuyList.value.map((item) => ({
          sku_id: item.sku_id,
          quantity: 1,
          discount_type: 'NONE' as const,
          landing_page_id: props.landingPageData.id,
          activity_id: item.activity_id
        }))
      ],
      recipient_info: userStore.getRecipientInfo(),
      discount_type: discount.value.type,
      multilevel_reflux_setting_id: discount.value.id,
      landing_page_id: props.landingPageData.id
    },
    {
      ignoreApiCodes: [700003]
    }
  );
  switch (response.__error) {
    case undefined: {
      if (response.code === 700003) {
        shippingFee.value = undefined;
      } else {
        const item = response.data;
        const fee = item?.shipping_fee ?? -1;
        shippingFee.value = fee;
      }
    }
  }
};

const userStore = $store.user();
const userAddress = computed(() => userStore.userAddress);
const quantity = ref(1);
const maxQuantity = computed(() => {
  if (!currentProduct.value || !product.value) return undefined;
  const inventory = currentProduct.value.inventory;
  if (product.value.quota_type === 'NO_QUOTA') return inventory;
  const maxPerBuy = product.value.quota_purchase_rule?.max_per_buy;
  return maxPerBuy ? Math.min(inventory, maxPerBuy) : inventory;
});
watch(
  () =>
    [
      userStore.userAddress?._t,
      currentProduct.value,
      quantity.value,
      handyBuyList.value
    ] as const,
  (val) => {
    if (val[0] && val[1]) getShippingInfo();
  },
  { immediate: true }
);
const remark = ref('');
const editingRemark = ref('');
const isShowRemarkPopup = ref(false);
const showRemark = () => {
  editingRemark.value = remark.value;
  isShowRemarkPopup.value = true;
};
const sumitRemarkHandle = () => {
  remark.value = editingRemark.value;
  isShowRemarkPopup.value = false;
};
watch(isShowRemarkPopup, (val) => {
  if (val) {
    emits('show-popper');
  } else {
    emits('hide-popper');
  }
});

const disabledText = computed(() => {
  if (!currentProduct.value) return '无效商品';
  if (!currentProduct.value.inventory) return '无库存';
  if (!currentProduct.value.sale_status) return '无库存';
  if (currentProduct.value.inventory < quantity.value) return '库存不足';
  if (userAddress.value === undefined) return '请选择地址';
  if (shippingFee.value === undefined) return '运费计算中 请稍后';
  return '';
});

const submitOrder = async () => {
  if (!currentProduct.value) return;
  uni.showLoading({ mask: true });
  const response = await $api.postOrderSubmitLandingOrder({
    detail_list: [
      {
        sku_id: currentProduct.value.id,
        quantity: quantity.value,
        discount_type: discount.value.type,
        multilevel_reflux_setting_id: discount.value.id,
        landing_page_id: props.landingPageData.id
      },
      ...handyBuyList.value.map((item) => ({
        sku_id: item.sku_id,
        quantity: 1,
        discount_type: 'NONE' as const,
        landing_page_id: props.landingPageData.id,
        activity_id: item.activity_id
      }))
    ],
    recipient_info: userStore.getRecipientInfo(),
    merchant_id: currentProduct.value.merchant_id,
    discount_type: discount.value.type,
    customer_remark: remark.value,
    landing_page_id: props.landingPageData.id,
    callback_param: props.queryData.onlyid,
    ascribe_type: props.queryData.ascribe_type
  });
  uni.hideLoading();
  switch (response.__error) {
    case undefined: {
      // #ifdef MP-ALIPAY
      if (response.data.pay_product === 'MERGE_PAY') {
        const tradeNo = response.data.merge_no ?? response.data.trade_no;
        await payOrder(tradeNo, { bizType: 'merge_order' });
      } else {
        await payOrder(response.data.trade_no);
      }
      // #endif
      // #ifdef MP-WEIXIN
      await payOrder({
        timeStamp: response.data.pay_we_chat?.timeStamp,
        nonceStr: response.data.pay_we_chat?.nonceStr,
        package: response.data.pay_we_chat?.packageVal,
        signType: response.data.pay_we_chat?.signType,
        paySign: response.data.pay_we_chat?.paySign
      });
      // #endif
      uni.reLaunch({ url: '/pages/order/order-page' });
      break;
    }
  }
};
</script>

<style lang="scss" scoped>
.header {
  line-height: 50rpx;
  font-size: 32rpx;
  font-weight: bold;
  text-align: center;
}

.product-select-block {
  padding: 20rpx 24rpx;
  margin: 0 24rpx;
  border-radius: 16rpx;
  background-color: white;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12rpx;
  & + & {
    margin-top: 24rpx;
  }

  .product-info {
    display: flex;
    align-items: center;
    gap: 16rpx;
    .product-info-content {
      flex: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      gap: 8rpx;
      .product-name {
        display: -webkit-box;
        font-size: 30rpx;
        font-weight: bold;
        line-height: 42rpx;
        overflow: hidden;
        text-overflow: ellipsis;
        word-break: break-all;
        -webkit-box-orient: vertical;
        line-clamp: 2;
        -webkit-line-clamp: 2;
        .tag {
          display: inline-flex;
          margin-right: 8rpx;
          margin-bottom: 3rpx;
          height: 32rpx;
          line-height: 32rpx;
          align-items: center;
          justify-content: center;
          color: white;
          white-space: nowrap;
          font-size: 24rpx;
          font-weight: normal;
          width: 60rpx;
          border-radius: 6rpx;
          vertical-align: middle;
          &.prime {
            background: linear-gradient(90deg, #ab6a12, #402302);
          }
          &.hot-selling {
            background: linear-gradient(90deg, #fc7529, #e92d00);
          }
          &.new-arrival {
            background: linear-gradient(90deg, #62d60d, #13ad5b);
          }
        }
      }
      .product-tag-list {
        height: calc(38rpx + 2px);
        display: flex;
        flex-wrap: wrap;
        gap: 8rpx;
        overflow: hidden;
        .product-tag {
          line-height: 38rpx;
          color: #ff2f3b;
          border-radius: 2rpx;
          border: 1px solid #ff2f3b;
          padding: 0 8rpx;
        }
      }
      .product-price {
        display: flex;
        align-items: baseline;
        gap: 0 8rpx;
        white-space: nowrap;
        .label {
          flex-shrink: 0;
        }
        .market-price {
          color: #999999;
          text-decoration: line-through;
          overflow: hidden;
          text-overflow: ellipsis;
          word-break: break-all;
          white-space: nowrap;
        }
      }
    }
  }
  .address-item {
    display: flex;
    align-items: center;
    gap: 24rpx;
    .address-content {
      flex: 1;
      min-width: 0;
      .address-main {
        font-weight: bold;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        word-break: break-all;
        margin-bottom: 8rpx;
      }
      .address-sub {
        color: #999999;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        word-break: break-all;
        display: inline-flex;
        gap: 0 8rpx;
      }
    }
    .alipay-holder {
      color: #007afe;
      flex: 1;
      min-width: 0;
    }
    .weixin-holder {
      color: #07c160;
    }
  }

  .spec-content {
    display: flex;
    flex-direction: column;
    gap: 24rpx;
  }
  .spec-group {
    margin-bottom: 12rpx;
    .spec-title {
      font-size: 32rpx;
      margin-bottom: 24rpx;
    }
    .spec-list {
      display: flex;
      flex-wrap: wrap;
      gap: 16rpx 24rpx;
      .spec-item {
        position: relative;
        max-width: calc(100% - 50rpx);
        box-sizing: border-box;
        line-height: 60rpx;
        font-size: 30rpx;
        border: 1px solid #f5f6fa;
        background-color: #f5f6fa;
        border-radius: 16rpx;
        padding: 0 24rpx;
        transition:
          border 0.3s,
          background-color 0.3s,
          color 0.3s;
        .text {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          word-break: break-all;
        }
        &.active {
          border: 1px solid #ff2f3b;
          background-color: rgba(255, 47, 59, 0.1);
          .text {
            color: #ff2f3b;
          }
        }
        &.sold-out {
          border: 1px solid rgba(245, 246, 250, 0.5);
          background-color: rgba(245, 246, 250, 0.5);
          .text {
            color: rgba(51, 51, 51, 0.5);
          }
          &::after {
            content: '售罄';
            position: absolute;
            z-index: 1;
            right: 0;
            top: 0;
            transform: translate(80%, -50%);
            background-color: #cccccc;
            border-radius: 18rpx 18rpx 18rpx 0;
            height: 36rpx;
            width: 80rpx;
            font-size: 24rpx;
            line-height: 36rpx;
            color: white;
            font-weight: 300;
            text-align: center;
          }
        }
        &.sold-out.active {
          border: 1px solid #cccccc;
        }
      }
    }
  }

  .product-select-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20rpx;
    .label {
      font-size: 32rpx;
      flex-shrink: 0;
    }
    .purchase-rule {
      color: #ff2f3b;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      word-break: break-all;
    }
    .content {
      font-size: 30rpx;
      flex: 1;
      min-width: 0;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      gap: 12rpx;
    }
    .placeholder {
      color: #999999;
    }
  }

  .shipping-item {
    display: flex;
    align-items: center;
    gap: 24rpx;
    .main {
      font-weight: bold;
      flex: 1;
      min-width: 0;
    }
    .sub {
      color: #999999;
    }
  }
}
.order-info-block {
  padding: 24rpx;
  margin: 0 24rpx;
  border-radius: 16rpx;
  background-color: white;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12rpx;
  margin-top: 24rpx;
  .order-info-item {
    min-height: 60rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8rpx;
    .label {
      font-size: 32rpx;
      flex-shrink: 0;
    }
    .content {
      font-size: 30rpx;
      flex: 1;
      min-width: 0;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      gap: 12rpx;
      .remark {
        flex: 1;
        min-width: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        word-break: break-all;
        text-align: right;
        &.placeholder {
          color: #999999;
          font-weight: 300;
        }
      }
    }
  }
}

.divider {
  height: 1px;
  background-color: #f4f4f4;
}

.submit-button-container {
  margin: 24rpx 24rpx 0;
  padding: 10rpx 0;
}
</style>
